﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Graphics.PackedVector;

namespace ProceduralGolf
{
    class TextureCircleDrawer : TextureEffect
    {
        private GraphicsDevice graphics;
        private Effect drawEffect;
        private RenderTarget2D clearedTarget;

        public TextureCircleDrawer(Game game)
        {
            this.graphics = game.GraphicsDevice;
            drawEffect = game.Content.Load<Effect>("circledrawer");
            spriteBatch = spriteBatch = new SpriteBatch(graphics);
        }

        private RenderTarget2D getRenderTarget(int width, int height)
        {

            if(clearedTarget == null)
            {
                clearedTarget = new RenderTarget2D(graphics, width, height, 1, graphics.PresentationParameters.BackBufferFormat);
            }
            else if(clearedTarget.Width != width || clearedTarget.Height != height)
            {
                clearedTarget.Dispose();
                clearedTarget = new RenderTarget2D(graphics, width, height, 1, graphics.PresentationParameters.BackBufferFormat);
            }
            return clearedTarget;
        }

        public Texture2D draw(Texture2D tex, List<Circle> circles, Color color)
        {
            Texture2D result = tex;
            foreach (Circle c in circles)
            {
                result = draw(result, c, color);
            }
            return result;
        }

        public Texture2D draw(Texture2D tex, Circle circle, Color color)
        {
            GraphicsMutex.GetMutex().WaitOne();

            Texture2D result;
            RenderTarget2D target = this.getRenderTarget(tex.Width, tex.Height);
            DepthStencilBuffer stencilBuffer = new DepthStencilBuffer(graphics, tex.Width, tex.Height, graphics.DepthStencilBuffer.Format, target.MultiSampleType, target.MultiSampleQuality);
            graphics.SetRenderTarget(0, target);
            DepthStencilBuffer oldBuffer = graphics.DepthStencilBuffer;
            graphics.DepthStencilBuffer = stencilBuffer;
            graphics.Clear(Color.Black);

            drawEffect.Begin();

            drawEffect.Parameters["center"].SetValue(circle.Center);
            drawEffect.Parameters["radius"].SetValue(circle.Radius);
            drawEffect.Parameters["color"].SetValue(color.ToVector4());
            drawEffect.Parameters["textureSize"].SetValue(new Vector2(tex.Width, tex.Height));

            foreach (EffectPass pass in drawEffect.CurrentTechnique.Passes)
            {
                spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
                pass.Begin();

                spriteBatch.Draw(tex, new Rectangle(0, 0, tex.Width, tex.Height), Color.White);
                pass.End();
                spriteBatch.End();
            }

            drawEffect.End();

            graphics.SetRenderTarget(0, null);
            graphics.DepthStencilBuffer = oldBuffer;

            //oldBuffer.Dispose();
            result = target.GetTexture();

            stencilBuffer.Dispose();

            GraphicsMutex.GetMutex().ReleaseMutex();

            return result;

        }

        //public Texture2D draw(Texture2D tex, Circle circle, Color color)
        //{
        //    Texture2D result;
        //    RenderTarget2D target = this.getRenderTarget(tex.Width, tex.Height);
            
        //    graphics.SetRenderTarget(0, target);

        //    drawEffect.Begin();

        //    drawEffect.Parameters["center"].SetValue(circle.Center);
        //    drawEffect.Parameters["radius"].SetValue(circle.Radius);
        //    drawEffect.Parameters["color"].SetValue(color.ToVector4());
        //    drawEffect.Parameters["textureSize"].SetValue(new Vector2(tex.Width, tex.Height));

        //    foreach (EffectPass pass in drawEffect.CurrentTechnique.Passes)
        //    {
        //        spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
        //        pass.Begin();

        //        spriteBatch.Draw(tex, new Rectangle(0, 0, tex.Width, tex.Height), Color.White);
        //        pass.End();
        //        spriteBatch.End();
        //    }

        //    drawEffect.End();


        //    graphics.SetRenderTarget(0, null);
        //    result = target.GetTexture();
        //    //target.Dispose();

        //    return result;

        //}

    }
}
